/**
 * @description:
 * @file: class.ts
 * @author: Evan
 * @date: 2025.06.24 11:49:18
 * @week: 周二
 * @version: V
 */

import type { ThreeModelItem } from 'three-scene/types/model.d.ts'
import * as MS from './data/methods'

const { THREE } = MS

export class Scene extends MS.Scene {
  // 建筑集合
  buildingGroup?: InstanceType<typeof THREE.Group>

  // 动画模型集合
  animateModels: InstanceType<typeof THREE.Object3D>[] = []

  // 水面
  water?: ReturnType<typeof MS.createWater>
  constructor(options: ConstructorParameters<typeof MS.Scene>[0]) {
    super(options)

    // 时间生成器
    this.createClock()

    // 建筑组
    this.addBuildingGroup()
  }

  modelAnimate(): void {
    let delta = this.clock?.getDelta() as number
    // 模型动画
    this.modelAnimateUpdate(delta)
  }

  // 添加建筑组
  addBuildingGroup() {
    const group = new THREE.Group()
    group.name = '建筑组'
    this.buildingGroup = group
    this.addObject(group)
  }
  // 清除场景建筑
  clearBuilding() {
    if (this.buildingGroup) {
      this.disposeObj(this.buildingGroup)
    }

    this.animateModels = []
    this.addBuildingGroup()
  }
  // 添加建筑
  addBuilding(...obj: ThreeModelItem[]) {
    if (this.buildingGroup) {
      this.buildingGroup.add(...obj)
    }
  }

  // 添加水面
  addWater(waterName = '水面004') {
    const obj = this.buildingGroup?.getObjectByName(waterName)
    if (!obj) return

    const water = MS.createWater()
    water.rotation.x = -Math.PI * 0.5

    // const water = MS.createWater(obj as MS.THREE.Mesh)

    // 获取世界坐标
    water.position.copy(obj.getWorldPosition(new THREE.Vector3()))
    // 转换世界旋转角度
    // const worldMatrix = obj.matrixWorld
    // const position = new THREE.Vector3()
    // const quaternion = new THREE.Quaternion()
    // const scale = new THREE.Vector3()
    // worldMatrix.decompose(position, quaternion, scale)
    // const euler = new THREE.Euler().setFromQuaternion(quaternion)
    // water.rotation.copy(euler)
    // // 转换世界缩放大小
    // water.scale.copy(obj.getWorldScale(new THREE.Vector3()))

    if (this.water) {
      this.scene.remove(this.water)
    }
    this.water = water

    // water.position.y += 10
    obj.visible = false
    this.addBuilding(this.water)
  }

  ///////////////////////////
  /////////// 模型动画 ///////////
  ///////////////////////////
  // 添加模型动画
  addModelAnimate(
    model: ThreeModelItem,
    animations = [],
    play: boolean = true,
    timeScale: number = 1
  ) {
    MS.createModelAnimate(model, animations, play, timeScale)
    this.animateModels.push(model)
  }
  // 模型动画
  modelAnimateUpdate(delta: number) {
    if (this.animateModels.length) {
      this.animateModels.forEach((el: InstanceType<typeof THREE.Object3D>) => {
        if (el.userData && el.userData.mixer) {
          el.userData.mixer.update(delta)
        }
      })
    }
  }

  render() {
    this.renderer.renderAsync(this.scene, this.camera)
  }
  createScene() {
    return new THREE.Scene()
  }

  createDirectionalLight(color: string | number, intensity: number) {
    return new THREE.DirectionalLight(color, intensity)
  }

  createAmbientLight(color: string | number, intensity: number) {
    return new THREE.AmbientLight(color, intensity)
  }

  createRender() {
    return new THREE.WebGPURenderer(this.options.render)
  }

  dispose() {
    super.dispose()
  }
}
